﻿using System;
using System.Collections;
using System.Collections.Generic;
using Common.Utils;
using Game.Kernel;
using Game.Logic.Data;
using Game.Logic.Events;
using Game.Logic.Manager;
using NetFramework;
using Sproto;
using UIFramework;
using UnityEngine;

using BaseEvent = Common.Utils.BaseEvent;

namespace Game.Logic
{
    public class GameModelEvent : GameBaseModelEvent
    {
        private GameDataType m_dataType;
        public GameDataType DataType { get => m_dataType; set => m_dataType = value; }
        public object[] Params { get; private set; }

        protected GameModelEvent(GameDataType _dataType, GameBaseData _gameData, params object[] _params)
        {
            DataType = _dataType;
            Data = _gameData;
            Params = _params;
        }

        protected GameModelEvent(params object[] _params)
        {
            Params = _params;
        }

        public static GameModelEvent Create(GameDataType _dataType, GameBaseData _gameData, params object[] _params)
        {
            return new GameModelEvent(_dataType, _gameData, _params);
        }

        public static GameModelEvent Create(params object[] _params)
        {
            return new GameModelEvent(_params);
        }
    }

    public class GameModel : GameBaseModel
    {
        public GameUserData GameUserData { private set; get; }
        public GameServerData GameServerData { private set; get; }

        private bool IsGameLoginUIEnter { set; get; }


        private void InitGameData()
        {
            GameVersionManager.Instance.InitGameVersion();

            // todo:暂时先放这里 没想清楚放哪
            // 设置UI背景
            Texture2D tex = (Texture2D)ResManager.Instance.Load("Textures/login_bg");
            GameUIManager.Instance.SetBackgroundImage(tex);
            //GameUIManager.Instance.SetBackgroundImageEnable(false);

            GameUserData = GameBaseData.Create<GameUserData>(GameDataType.GameUser);
            GameServerData = GameBaseData.Create<GameServerData>(GameDataType.GameServer);
        }

#region Controller Event
        public void OnGameStatusInit()
        {
            InitGameData();
            IsGameLoginUIEnter = false;
            GameUIManager.Instance.OpenUI(ENUM_UITYPE.LOGIN);
            CoroutineController.Instance.StartCoroutine(CheckGameInit());
            GameEventManager.Instance.RegisterEventListener(GameEventType.GameUIEnter, OnGameEvent);
        }

        IEnumerator CheckGameInit()
        {
            while (true)
            {
                bool isDone = true;
                isDone &= GameVersionManager.Instance.IsInitDown;
                isDone &= IsGameLoginUIEnter;

                if (isDone)
                    break;
                else
                    yield return new WaitForSeconds(0.1f);
            }
            OnGameStatusInitDone();
        }

        void OnGameStatusInitDone()
        {
            ClientKernel.Instance.GameController.SetGameStatus(GameStatus.ConnectServer);
        }

        public void OnGameStatusConnectServer()
        {
            GatewayInfo? info = GameGatewayManager.Instance.GetCurGatewayInfo();
            if (info == null)
                throw new Exception(string.Format("GetwayInfo is null! please check '{0}.lua'!", GameDefine.GAME_CONFIG_GATEWAY));
            NetworkManager.Instance.Connect(info?.addr, System.Convert.ToUInt16(info?.port), OnConnectedServer);
        }

        public void OnConnectedServer()
        {
            ClientKernel.Instance.GameController.SetGameStatus(GameStatus.EnterLogin);

        }

        public void OnGameStateEnterLogin()
        {
            // GameUIManager.Instance.CloseUI();
            // GameUIManager.Instance.OpenUI(ENUM_UITYPE.LOGIN);
        }

        public void OnGameStatusGetVersion()
        {
            GameVersionManager.Instance.DownloadVersionFile(OnGetVersionCompleted);
        }


        public void OnGetVersionCompleted()
        {
            ClientKernel.Instance.GameController.SetGameStatus(GameStatus.CheckVersion);
        }

        public void OnGameStateCheckVersion()
        {
            GameVersionDiff? diff = GameVersionManager.Instance.CompareVersion();
            CoroutineController.Instance.StartCoroutine(CheckGameCheckVersion(diff));
        }

        IEnumerator CheckGameCheckVersion(GameVersionDiff? diff)
        {
            yield return null;
            List<List<string>> differences = diff?.GetDifferences();
            if (differences.Count < 1)
            {
                ClientKernel.Instance.GameController.SetGameStatus(GameStatus.EnterLogin);
            }
            else
            {
                ClientKernel.Instance.GameController.SetGameStatus(GameStatus.Downloading);
            }
            yield return null;
        }

        public void OnGameStateDownloading()
        {
            GameVersionDiff? diff = GameVersionManager.Instance.CompareVersion();
            List<List<string>> differences = diff?.GetDifferences();
            DownloadResult resul = GameVersionManager.Instance.SyncToLastVersion(differences);
            CoroutineController.Instance.StartCoroutine(CheckGameDownloading(resul));
        }

        public IEnumerator CheckGameDownloading(DownloadResult _result)
        {
            while (!_result.IsDone)
            {

                Debug.LogFormat("GameDownloading progress is {0}", _result.Progress);
                yield return new WaitForSeconds(0.1f);
            }
            Debug.LogFormat("GameDownloading progress is {0}", _result.Progress);
            Debug.LogFormat("GameDownloading done");
            // 
            yield return null;
        }

        public virtual void OnUpdateGameStatus(GameStatus _cur, GameStatus _pre)
        {
            switch (_cur)
            {
                case GameStatus.Init:
                    OnGameStatusInit();
                    break;
                case GameStatus.ConnectServer:
                    OnGameStatusConnectServer();
                    break;
                case GameStatus.EnterLogin:
                    OnGameStateEnterLogin();
                    break;
                case GameStatus.GetVersion:
                    OnGameStatusGetVersion();
                    break;
                case GameStatus.CheckVersion:
                    OnGameStateCheckVersion();
                    break;
                case GameStatus.Downloading:
                    OnGameStateDownloading();
                    break;
                default:
                    break;
            }
        }
#endregion


#region Game Event
        public void OnGameEvent(BaseEvent gameEvent)
        {
            GameUIEvent uiEvent = gameEvent.Cast<GameUIEvent>();
            if (null != uiEvent)
            {
                OnGameUIEvent(uiEvent);
                return;
            }

        }

        public void OnGameUIEvent(GameUIEvent uiEvent)
        {
            switch ((GameEventType)uiEvent.EventType)
            {
                case GameEventType.GameUIEnter:
                    switch (uiEvent.UIType)
                    {
                        case ENUM_UITYPE.LOGIN:
                            IsGameLoginUIEnter = true;
                            break;
                        default:
                            break;
                    }
                    break;
                default:
                    break;
            }
        }
#endregion


#region Net Msg
        //private void Net_RequestHandshake()
        //{



        //    string clientkey = GameTools.Base64EncodeFromBytes(GameServerData.ClientKey);

        //    SPNetMsg msg = new SPNetMsg();
        //    msg.ProtoType = (ushort)MessageType.Login;
        //    msg.ProtoName = "handshake";
        //    msg.Data = new SprotoObject(msg.ProtoName);
        //    msg.Data["client_key"] = clientkey;

        //    // Debug.LogFormat("Net_RequestHandshake send");
        //    NetworkManager.Instance.Send(msg, Net_ResponseHandshake);
        //}

        //private void Net_ResponseHandshake(SprotoObject _response)
        //{
        //    // Debug.LogFormat("Net_ResponseHandshake recv");
        //    // ClientKernel.Instance.GameController.SetGameStatus(GameStatus.GetVersion);



        //    Net_RequestAuth("Aliner", "11111");
        //}

        //private void Net_RequestAuth(string _accountName, string _accountPwd)
        //{
        //    SPNetMsg msg = new SPNetMsg();
        //    msg.ProtoType = (ushort)MessageType.Login;
        //    msg.ProtoName = "auth";
        //    msg.Data = new SprotoObject(msg.ProtoName);
        //    msg.Data["acc_secret"] = "";//_clientKey;
        //}
#endregion
    }
}

